package com.iris.live.services.common;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.iris.live.services.common.reconsitution.CollectionUtils;
import com.iris.live.services.data.models.*;
import com.iris.live.services.data.repositories.*;
import com.iris.live.services.report.data.IReportDataConvertor;
import com.iris.live.services.report.data.ReportContext;
import com.iris.live.services.report.data.baseline.BaseUnit;
import com.iris.live.services.report.data.baseline.BaselineContext;
import com.iris.live.services.report.data.carmodelline.CarModelUnit;
import com.iris.live.services.report.data.carmodelline.CarModellineContext;
import com.iris.live.services.report.data.matchers.Matcher;
import com.iris.live.services.report.data.orgline.OrgUnit;
import com.iris.live.services.report.data.orgline.OrglineContext;
import com.iris.live.services.report.data.timeline.TimeUnit;
import com.iris.live.services.report.data.timeline.TimelineContext;
import com.iris.live.services.services.BrandService;
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 报表X轴维度工具类
 * Created by HangLiu on 2017/8/23.
 */
@Component()
public class LineContextUtil {
    public static final int timeLine = 1;  //时间维度
    public static final int orgLine = 2;  //组织架构维度
    public static final int modelLine = 3;//其他维度(品牌维度)
    public static final int channellLine = 4;//其他维度(渠道维度)
    public static final int financeOrgLine = 5; // 其他维度(金融机构维度)
    public static final int carModel = 6; // 品牌车型维度

    private static final Logger logger = LoggerFactory.getLogger(LineContextUtil.class);

    private static Lsh经销商表Repository lsh经销商表Repository;

    private static IReportDataConvertor timelineConvertor;

    private static IReportDataConvertor orglineConvertor;

    private static IReportDataConvertor baselineConvertor;

    private static IReportDataConvertor baseOtherlineConvertor;

    private static IReportDataConvertor carModellineConvertor;

    private static 用户Repository userRepository;

    private static ReportConfigRepository reportConfigRepository;

    private static Lsh车型Repository lsh车型Repository;

    private static CarRepository carRepository;

    private static BrandService  brandService;

    private static Lsh金融机构设置Repository lsh金融机构设置Repository;

    private static Itask基础设置Repository itask基础设置Repository;

    //构造context ：包括权限等级，x轴的维度（时间维度，组织架构维度）
    public static ReportContext getReportContext(Map info) throws Exception {
        if(StringUtils.isNullOrBlank(ThreadContext.get("LIVE_USERNAME"))){
            ThreadContext.put("LIVE_USERNAME", info.get("fr_username") == null ? "" : info.get("fr_username").toString());
        }

        ReportContext context = null;
        //判断权限
        setAuthorityPermit(info);
        // 判断品牌、车系、车型
        setBrandCarType(info);
        //判断时间维度
        info = ReportUtils.setDateSection(info);
        //判断维度扩展
        Integer type = Integer.valueOf(info.get("displayType").toString());
        switch (type) {
            case timeLine:  // 时间维度
                context = getTimelineContext(info);
                break;
            case orgLine:  // 组织架构维度
                context = getOrglineContext(info);
                break;
            case modelLine:  // 品牌维度
                context = getModellineContext(info, getModelUnitList(info, getModelList(info), "品牌"));
                break;
            case channellLine:  // DCC线索维度
                context = getModellineContext(info, getModelUnitList(info, getChannelList(), "cust_channel"));
                break;
            case financeOrgLine: // 金融机构维度
                context = getModellineContext(info, getModelUnitList(info, getFinanceOrgList(), "financeOrg"));
                break;
            case carModel:  // 车型维度
                context = getCarModellineContext(info);
                break;
        }
        return context;
    }

    public static ReportContext getReportDayLineContext(Map info) throws Exception {
        String year = info.get("selYear").toString(), month = info.get("selMonth").toString();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateFormatUtils.getFormatDate(year + "-" + month + "-01", DateFormatUtils.TIME_FORMAT_STR_YYYY_MM_DD));
        List<BaseUnit> list = new ArrayList<>();
        for (int i = 1; i <= calendar.getActualMaximum(Calendar.DAY_OF_MONTH); i++) {
            list.add(new BaseUnit(BaseUnit.BaseType.NORMAL, String.valueOf(i), "day", i));
        }
        return getModellineContext(info, list);
    }

    /**
     * * 构造时间维度的扩展上下文 报表通用私有方法
     *
     * @param info
     * @return
     */
    private static TimelineContext getTimelineContext(Map info) {
        TimelineContext context = new TimelineContext();
        context.setTimeColumn("date");//时间维度对应查出数据的列名（此处为月份）
        context.addTimeUnit(getTimeUnitList(info));//注入构建的X轴
        context.setConvertor(timelineConvertor);// 注入时间转换器
        context.setMatcher(new Matcher());//注入品牌判断器
        if (!(info.get("selBrandSumName") == null || info.get("selBrandSumName").toString().trim().isEmpty())) {
            context.setDynamicIndicatorValues(info.get("selBrandSumName").toString());//注入前端填写品牌组合
            String dataGroup = "permit,品牌,date";//品牌分组忽略字段
            context.setDataGroupKeys(dataGroup);//置入品牌分组忽略字段
            //设置品牌所在树的等级
            context.setDynamicIndicatorLevel(2);//品牌节点在第二层
            //设置累加参数
            context.setIndicatorGroupKey("品牌");
        }

        if("其他".equals(info.get("permit"))){
            info.put("permit", "其他cta");
        }
        context.getParams().putAll(info);
        return context;
    }

    /**
     * 构造组织维度的扩展上下文 报表通用私有方法
     *
     * @param info
     * @return
     */
    private static OrglineContext getOrglineContext(Map info) {
        OrglineContext context = new OrglineContext();
        context.addOrgUnit(getOrgUnitList(info));////注入构建的X轴
        context.setConvertor(orglineConvertor);// 注入组织架构转换器
        context.setMatcher(new Matcher());//注入品牌判断器
        if (!(info.get("selBrandSumName") == null || info.get("selBrandSumName").toString().trim().isEmpty())) {
            context.setDynamicIndicatorValues(info.get("selBrandSumName").toString());//注入前端填写品牌组合
            String dataGroup = "品牌,集团,许可_LSH,大区,大区_EN,小区,小区_EN,CTA,CTA_EN,许可_BMBS,经销商名,经销商名_EN,salesCode";//品牌分组忽略字段
            context.setDataGroupKeys(dataGroup);//置入品牌分组忽略字段
            //设置品牌所在树的等级
            context.setDynamicIndicatorLevel(2);//品牌节点在第二层
            //设置累加参数
            context.setIndicatorGroupKey("品牌");
        }

        if("其他".equals(info.get("permit"))){
            info.put("permit", "其他cta");
        }
        context.getParams().putAll(info);
        return context;
    }

    /**
     * 构造组织维度的扩展上下文 报表通用私有方法
     *
     * @param info
     * @return
     */
    private static BaselineContext getModellineContext(Map info, List<BaseUnit> list) {
        BaselineContext context = new BaselineContext();
        context.setUnits(list);////注入构建的X轴
        context.setConvertor(baselineConvertor);// 注入组织架构转换器
        context.setMatcher(new Matcher());//注入品牌判断器
        if (!(info.get("selBrandSumName") == null || info.get("selBrandSumName").toString().trim().isEmpty())) {
            context.setDynamicIndicatorValues(info.get("selBrandSumName").toString());//注入前端填写品牌组合
            String dataGroup = "permit,品牌";//品牌分组忽略字段
            context.setDataGroupKeys(dataGroup);//置入品牌分组忽略字段
            //设置品牌所在树的等级
            context.setDynamicIndicatorLevel(2);//品牌节点在第二层
            //设置累加参数
            context.setIndicatorGroupKey("品牌");
        }

        if("其他".equals(info.get("permit"))){
            info.put("permit", "其他cta");
        }
        context.getParams().putAll(info);
        return context;
    }

    private static BaselineContext getOtherlineContext(Map info, List<BaseUnit> list) {
        BaselineContext context = new BaselineContext();
        context.setUnits(list);////注入构建的X轴
        context.setConvertor(baseOtherlineConvertor);// 注入组织架构转换器
        context.setMatcher(new Matcher());//注入品牌判断器

        if("其他".equals(info.get("permit"))){
            info.put("permit", "其他cta");
        }
        context.getParams().putAll(info);
        return context;
    }


    /**
     * 车型维度上下文环境
     *
     * @param info
     * @return
     */
    private static CarModellineContext getCarModellineContext(Map info) {
        CarModellineContext context = new CarModellineContext();
        context.addUnits(getCarModelUnitList(info));////注入构建的X轴
        context.setConvertor(carModellineConvertor);// 注入组织架构转换器
        context.setMatcher(new Matcher());//注入品牌判断器

        if("其他".equals(info.get("permit"))){
            info.put("permit", "其他cta");
        }
        context.getParams().putAll(info);
        return context;
    }

    /**
     * 判断权限许可通用方法
     *
     * @param info
     */
    private static void setAuthorityPermit(Map info) {
        if (!StringUtils.isNullOrBlank(info.get("selDealerCode")) && !"all".equalsIgnoreCase(info.get("selDealerCode").toString()) && !"全部".equalsIgnoreCase(info.get("selDealerCode").toString())) {
            String permitLSH = info.get("selDealerCode").toString(); //许可lsh
            // 许可lsh转为许可_BMBS
            String permitBMBS = lsh经销商表Repository.getDistributorByPermitLSH(permitLSH).get(0).getBmbs(); // 开发库中，经销商表有经销商重复的脏数据，使用get(0)
            info.put("permit", permitBMBS);
            return;
        } else if (!StringUtils.isNullOrBlank(info.get("selPMACode")) && !"all".equalsIgnoreCase(info.get("selPMACode").toString()) && !"全部".equalsIgnoreCase(info.get("selPMACode").toString())) {
            info.put("permit", info.get("selPMACode").toString());
            return;
        } else if (!StringUtils.isNullOrBlank(info.get("selRegionCode")) && !"all".equalsIgnoreCase(info.get("selRegionCode").toString()) && !"全部".equalsIgnoreCase(info.get("selRegionCode").toString())) {
            info.put("permit", info.get("selRegionCode").toString());
            return;
        } else {
            info.put("permit", "");
        }
    }

    /**
     * 设置品牌、车系、车型
     *
     * @param info
     */
    private static void setBrandCarType(Map info) {
        if (null != info.get("selModels") && !"all".equalsIgnoreCase(info.get("selModels").toString()) && !"全部".equalsIgnoreCase(info.get("selModels").toString())) {
            info.put("carType", info.get("selModels").toString());
            return;
        } else if (null != info.get("selSystem") && !"all".equalsIgnoreCase(info.get("selSystem").toString()) && !"全部".equalsIgnoreCase(info.get("selSystem").toString())) {
            info.put("carType", info.get("selSystem").toString());
            return;
        } else if (null != info.get("selBrand") && !"all".equalsIgnoreCase(info.get("selBrand").toString()) && !"全部".equalsIgnoreCase(info.get("selBrand").toString())) {
            info.put("carType", info.get("selBrand").toString());
            return;
        } else {
            info.put("carType", "all");
            return;
        }
    }

    /**
     * 构造时间坐标值通用方法
     * 用于构造出 标题列中  年  季度  维度
     * 传入前端传参 MgtSalesReportVO
     *
     * @return
     */
    private static List<TimeUnit> getTimeUnitList(Map info) {
        List<TimeUnit> timeUnits = new ArrayList<>();
        if("销售管理报表".equals(info.get("reportCode"))){
            timeUnits.add(new TimeUnit(TimeUnit.TimeType.YEAR, info.get("selectYear").toString(),info.get("selectYear").toString() + "(YTD)", 1));
        }else{
            timeUnits.add(new TimeUnit(TimeUnit.TimeType.YEAR, info.get("selectYear").toString(), 1));
        }
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.QUARTER, "Q1", 2));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "01", 3));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "02", 4));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "03", 5));

        timeUnits.add(new TimeUnit(TimeUnit.TimeType.QUARTER, "Q2", 6));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "04", 7));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "05", 8));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "06", 9));

        timeUnits.add(new TimeUnit(TimeUnit.TimeType.QUARTER, "Q3", 10));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "07", 11));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "08", 12));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "09", 13));

        timeUnits.add(new TimeUnit(TimeUnit.TimeType.QUARTER, "Q4", 14));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "10", 15));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "11", 16));
        timeUnits.add(new TimeUnit(TimeUnit.TimeType.MONTH, "12", 17));
        return timeUnits;
    }

    /**
     * 构造构造集团许可坐标轴通用方法
     * 用于构造出组织架构维度的坐标
     * 传入前端传参 MgtSalesReportVO
     *
     * @return
     */
    private static List<BaseUnit> getModelUnitList(Map info, List<String> list, String name) {
        List<BaseUnit> getBaseUnitList = new ArrayList<>();
        getBaseUnitList.add(new BaseUnit(BaseUnit.BaseType.TOTAL, "总计", "total", 1));
        int i = 2;
        for (String item : list) {
            getBaseUnitList.add(new BaseUnit(BaseUnit.BaseType.SINGLE, item, name, i));
            i++;
        }
        return getBaseUnitList;
    }

    private static List<BaseUnit> getOtherUnitList(Map info, List<String> list, String name) {
        List<BaseUnit> getBaseUnitList = new ArrayList<>();
        int i = 1;
        for (String item : list) {
            getBaseUnitList.add(new BaseUnit(BaseUnit.BaseType.SINGLE, item, name, i));
            i++;
        }
        return getBaseUnitList;
    }

    public static ReportContext getReportContextByStockForecast(Map info, Integer type) {
        try {
            //判断权限
            setAuthorityPermit(info);
            if (type == 1) {
                return getOtherlineContext(info, getOtherUnitList(info, getColorByCar(info.get("selBrand").toString(), info.get("selClass").toString(), info.get("selType").toString()), "颜色"));
            }else if (type == 2) {
                return getOtherlineContext(info, getOtherUnitList(info, getCarDetailedByCar(info.get("selBrand").toString(), info.get("selClass").toString(), info.get("selType").toString()), "车款"));
            }else if (type == 3) {
                BaselineContext context = getOtherlineContext(info, getOtherUnitList(info, Lists.newArrayList("预计新增采购数"), "预计新增采购数"));
                context.getUnits().get(0).setType(BaseUnit.BaseType.NORMAL);
                return context;
            }else {
                return null;
            }
        } catch (Exception e) {
            logger.error("getReportContextByStockForecast构建X轴错误");
            return null;
        }
    }

    private static List<String> getModelList(Map info) {
        List<String> brands = new ArrayList<>();

        String selBrandName = info.get("selBrandName") == null ? "" : info.get("selBrandName").toString();
        if (StringUtils.isNotNullOrBlank(selBrandName) && !"all".equals(selBrandName) && !"全部".equals(selBrandName)) {
            brands.clear();
            brands.add(selBrandName);

            return brands;
        }

        selBrandName = info.get("carType") == null ? "" : info.get("carType").toString();
        if (StringUtils.isNotNullOrBlank(selBrandName) && !"all".equals(selBrandName) && !"全部".equals(selBrandName)) {
            brands.clear();
            brands.add(selBrandName);

            return brands;
        }

        selBrandName = info.get("selBrand") == null ? "" : info.get("selBrand").toString();
        if (StringUtils.isNotNullOrBlank(selBrandName) && !"all".equals(selBrandName) && !"全部".equals(selBrandName)) {
            brands.clear();
            brands.add(selBrandName);

            return brands;
        }

        return carRepository.getAvailableVehicleBrands(ThreadContext.get("LIVE_USERNAME"));
        //return lsh车型Repository.selectByModel();
    }

    private static List<String> getColorByCar(String selBrandname, String selClass, String selType) {
        List<String> list = lsh车型Repository.getColorByCar(selBrandname, selClass, selType);
        List<String> colors = Lists.newArrayList();
        for (String color : list) {
            if (!Strings.isNullOrEmpty(color)) {
                colors.addAll(Arrays.asList(color.split(";")));
            }
        }
        colors.add("其他");
        colors.add("总计");
        List c = colors.stream()
                .distinct()
                .collect(Collectors.toList());
        return c;
    }

    private static List<String> getCarDetailedByCar(String selBrandname, String selClass, String selType) {
        List<String> list = lsh车型Repository.getCarDetailedByCar(selBrandname, selClass, selType);
        list.add("其他");
        list.add("总计");
        return list;
    }

    private static List<String> getChannelList() {
        List<String> list = new ArrayList();
        list.add("散客");
        list.add("呼入");
        list.add("网络_汽车之家");
        list.add("网络_易车网");
        list.add("网络_爱卡汽车");
        list.add("网络_太平洋汽车网");
        list.add("网络_其他");
        list.add("主动集客");
        /*list.add("推荐");
        list.add("再购");*/
        return list;
    }

    private static List<String> getFinanceOrgList() {
        return lsh金融机构设置Repository.getFinanceOrgList();
    }

    /**
     * 构造构造品牌坐标轴通用方法
     * 用于构造出品牌维度的坐标 例如：集团 各大区总计、  集团 指定大区/cta 大区/cta下所有经销商
     * 传入前端传参 MgtSalesReportVO
     *
     * @return
     */
    private static List<OrgUnit> getOrgUnitList(Map info) {
        String permit = info.get("selDealerCode").toString();
        String selPMACode = info.get("selPMACode").toString();
        String selRegionCode = info.get("selRegionCode").toString();
        List<OrgUnit> getOrgUnitList = new ArrayList<>();
        if (logger.isDebugEnabled()) {
            logger.debug("selRegionCode={}, selPMACode={}, permit={}", selRegionCode, selPMACode, permit);
        }
        /* 如果选择指定经销商,维度为: 集团总计,大区总计,所在PMA总计,指定经销商*/
       /* if(!"all".equalsIgnoreCase( permit)&&permit!=null ){
            return getOrgUnitList;
        }*/
        //如果选择指定PMA（CTA）,维度为: 集团总计,PMA所在大区总计,PMA总计,PMA下经销商
        if (!"全部".equalsIgnoreCase(selPMACode) && !"all".equalsIgnoreCase(selPMACode) && !StringUtils.isNullOrBlank(selPMACode)) {
            getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.GROUP, "DCH", "集团", 1));
            getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.BIGAREA, selRegionCode, "大区_EN", 2));
            getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.CTA, selPMACode, "CTA_EN", 3));
            List<Lsh经销商表Model> permitList = lsh经销商表Repository.findByBigAreCtaPermitList(selRegionCode, selPMACode);
            int i = 4;
            for (Lsh经销商表Model item : permitList) {
                getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.PERMIT, item.getLsh(), "许可_LSH", i));
                i++;
            }
            return getOrgUnitList;
        }
        //如果选择 指定大区, 维度为: 集团总计,指定大区总计,大区下经销商
        else if (!"全部".equalsIgnoreCase(selRegionCode) && !"all".equalsIgnoreCase(selRegionCode) && !StringUtils.isNullOrBlank(selRegionCode)) {
            getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.GROUP, "DCH", "集团", 1));
            getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.BIGAREA, selRegionCode, "大区_EN", 2));
            List<Lsh经销商表Model> permitList = lsh经销商表Repository.findByBigArePermitList(selRegionCode);
            int i = 3;
            for (Lsh经销商表Model item : permitList) {
                if (!StringUtils.isNullOrBlank(item.getLsh())) {
                    getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.PERMIT, item.getLsh(), "许可_LSH", i));
                    i++;
                }
            }

            return getOrgUnitList;
        } else { //默认查询 集团总计 及各大区总计
            getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.GROUP, "DCH", "集团", 1));
            List<String> permitList = lsh经销商表Repository.getBIgAreasLiSt();
            int i = 2;
            for (String item : permitList) {
                getOrgUnitList.add(new OrgUnit(OrgUnit.OrgType.BIGAREA, item, "大区_EN", i));
                i++;
            }
        }
        return getOrgUnitList;
    }

    /**
     * 构建车型维度x轴（动态）
     *
     * @return
     */
    private static List<CarModelUnit> getCarModelUnitList(Map info) {
        List<CarModelUnit> units = new ArrayList<>();
        if (null == info.get("selBrand") && null == info.get("selSystem")) {
            logger.error("构建车型x轴维度失败。缺少参数：selBrand、selSystem。");
            return null;
        }
        String selBrand = info.get("selBrand").toString();  // 品牌参数
        String selSystem = info.get("selSystem").toString(); // 车系参数

        // 如果指定车系，则维度为：总计、品牌总计、车系总计、各个车型
        if (null != selSystem && !"all".equals(selSystem) && !"全部".equals(selSystem)) {
            units.add(new CarModelUnit(CarModelUnit.CarModelType.TOTAL, "总计", "总计", 1)); // 总计维度
            units.add(new CarModelUnit(CarModelUnit.CarModelType.BRAND, selBrand, "brand", 2)); // 品牌维度
            units.add(new CarModelUnit(CarModelUnit.CarModelType.SERIES, selSystem, "series", 3)); // 车系维度
            int i = 4;
            List<String> carModels = lsh车型Repository.getCarModelByBrandAndSeries(selBrand, selSystem);  // 获得车系下所有车型
            if (null != carModels && !carModels.isEmpty()) {
                for (String carModel : carModels) {
                    units.add(new CarModelUnit(CarModelUnit.CarModelType.MODEL, carModel, "model", i)); // 车型维度
                    i++;
                }
            }
        }
        // 如果指定品牌，则维度为：总计、品牌总计、各个车型
        else if (null != selBrand && !"all".equals(selBrand) && !"全部".equals(selBrand)) {
            units.add(new CarModelUnit(CarModelUnit.CarModelType.TOTAL, "总计", "总计", 1)); // 总计维度
            units.add(new CarModelUnit(CarModelUnit.CarModelType.BRAND, selBrand, "brand", 2)); // 品牌维度
            int i = 3;
            List<String> carModels = lsh车型Repository.getCarModelByBrand(selBrand);
            if (null != carModels && !carModels.isEmpty()) {
                for (String carModel : carModels) {
                    units.add(new CarModelUnit(CarModelUnit.CarModelType.MODEL, carModel, "model", i)); // 车型维度
                    i++;
                }
            }
        }
        // 默认维度为：总计、品牌总计
        else {
            units.add(new CarModelUnit(CarModelUnit.CarModelType.TOTAL, "总计", "总计", 1));  // 总计维度
            int i = 2;
            List<String> carBrands = lsh车型Repository.selectByModel();
            if (null != carBrands && !carBrands.isEmpty()) {
                for (String brand : carBrands) {
                    units.add(new CarModelUnit(CarModelUnit.CarModelType.BRAND, brand, "brand", i));  // 品牌维度
                    i++;
                }
            }
        }
        return units;
    }

    public static List<ReportConfig> getReportConifTree(String reportName) {
        List<ReportConfig> reportConfigList = reportConfigRepository.getReportConfigListByName(reportName);
        //构造reportConifg Map
        Map<String, ReportConfig> tempMap = new HashMap<>();
        List<String> brands = carRepository.getAvailableVehicleBrands(ThreadContext.get("LIVE_USERNAME"));

        //获取LSH 零售目标的 展示品牌信息，如果没有，初始化品牌信息
        Itask基础设置ModelPK itask基础设置ModelPK = new Itask基础设置ModelPK();
        itask基础设置ModelPK.set许可("LSH");
        itask基础设置ModelPK.set设置项目("LSH_RETAIL_TARGET");
        Itask基础设置Model itask基础设置Model = itask基础设置Repository.findOne(itask基础设置ModelPK);
        if (itask基础设置Model == null) {
            itask基础设置Model = new Itask基础设置Model();
            itask基础设置Model.set值("MB,MM,AMG,MB+MM+AMG,smart,VAN,DENZA");
        }

        List<ReportConfig> result = new ArrayList<>();
        String statType;
        //多品牌情况下处理配置项的动态修改
        List<ReportConfig> removed = new ArrayList<>(), added = new ArrayList<>();
        for (ReportConfig temp : reportConfigList) {
            if ("0".equals(temp.getParentCode())) {
                result.add(temp);
                tempMap.put(temp.getAinCode(), temp);
            }else {
                statType = temp.getStatType();
                if ("品牌".equals(statType) || "LSH TA".equals(statType)) {
                    if ("LSH TA".equals(statType)) {
                        brands = new ArrayList<>();
                        String[] carBrands = itask基础设置Model.get值().split(",");
                        for (String str : carBrands) {
                            brands.add(str);
                        }
                    }
                    List<ReportConfig> configs = addBrandStatConfig(temp, brands);
                    if (CollectionUtils.isNotEmpty(configs)) {
                        removed.add(temp); //移除库存存在的配置模板
                        for (ReportConfig config : configs) {
                            tempMap.put(config.getAinCode(), config);

                            added.add(config);
                        }
                    }
                } else if ("累计".equals(statType)) {
                    ReportConfig config = addTotalStatConfig(temp, brands);
                    tempMap.put(config.getAinCode(), config);
                    added.add(config);
                    removed.add(temp);
                } else {
                    tempMap.put(temp.getAinCode(), temp);
                }
            }
        }
        reportConfigList.removeAll(removed);
        reportConfigList.addAll(added);

        //循环构造树
        for (ReportConfig reportConfig : reportConfigList) {
            ReportConfig temp = tempMap.get(reportConfig.getParentCode());
            if (temp != null) {//判断父节点是否存在
                reportConfig.setParentConfig(temp);
                if (temp.getChildConfigs() == null) {
                    temp.setChildConfigs(new ArrayList<>());
                }
                temp.getChildConfigs().add(reportConfig);
            }
        }

        return result;
    }

    /**
     * 根据品牌已经模板记录动态生成报表配置记录就
     * @param template
     * @param brands
     */
    private static List<ReportConfig> addBrandStatConfig(ReportConfig template, List<String> brands){
        List<ReportConfig> configs = new ArrayList<>();
        for(String brand : brands){
            ReportConfig newReportConfig = new ReportConfig();

            newReportConfig.setAinCode(replaceBrandExpression(template.getAinCode(), brand));
            newReportConfig.setCategory(replaceBrandExpression(template.getCategory(), brand));
            newReportConfig.setText(replaceBrandExpression(template.getText(), brand));
            newReportConfig.setReportCode(replaceBrandExpression(template.getReportCode(), brand));
            newReportConfig.setParentCode(replaceBrandExpression(template.getParentCode(), brand));
            newReportConfig.setValueKey(replaceBrandExpression(template.getValueKey(), brand));
            newReportConfig.setMatchKey(replaceBrandExpression(template.getMatchKey(), brand));
            newReportConfig.setFormularExpression(replaceBrandExpression(template.getFormularExpression(), brand));
            newReportConfig.setRemark(replaceBrandExpression(template.getReportCode(), brand));
            newReportConfig.setProjectNameOrder(replaceBrandExpression(template.getProjectNameOrder(), brand));
            newReportConfig.setMatchItem(template.getMatchItem());
            newReportConfig.setMatcher(template.getMatcher());
            newReportConfig.setDataType(template.getDataType());
            newReportConfig.setPrecious(template.getPrecious());
            newReportConfig.setPriority(template.getPriority());
            newReportConfig.setRowType(template.getRowType());
            newReportConfig.setStatType(template.getStatType());
            //newReportConfig.setShown(template.getShown());

            configs.add(newReportConfig);
        }

        return configs;
    }

    private static String replaceBrandExpression(String origin, String targetBrand){
        if(StringUtils.isNullOrBlank(origin)) {
            return origin;
        }

        return origin.replace("{brand}", targetBrand);
    }
    /**
     * 根据品牌已经模板记录动态生成报表配置记录就
     * @param template
     * @param brands
     */
    private static ReportConfig addTotalStatConfig(ReportConfig template, List<String> brands){
        ReportConfig newReportConfig = new ReportConfig();

        newReportConfig.setAinCode(template.getAinCode());
        newReportConfig.setCategory(template.getCategory());
        newReportConfig.setText(template.getText());
        newReportConfig.setReportCode(template.getReportCode());
        newReportConfig.setParentCode(template.getParentCode());
        newReportConfig.setValueKey(template.getValueKey());
        newReportConfig.setMatchKey(template.getMatchKey());
        newReportConfig.setFormularExpression(template.getFormularExpression());
        newReportConfig.setRemark(template.getReportCode());
        newReportConfig.setProjectNameOrder(template.getProjectNameOrder());
        newReportConfig.setMatchItem(template.getMatchItem());
        newReportConfig.setMatcher(template.getMatcher());
        newReportConfig.setDataType(template.getDataType());
        newReportConfig.setPrecious(template.getPrecious());
        newReportConfig.setPriority(template.getPriority());
        newReportConfig.setRowType(template.getRowType());
        newReportConfig.setStatType(template.getStatType());

        String templateFormular = newReportConfig.getFormularExpression(), element;
        StringBuffer formular = new StringBuffer();
        if(StringUtils.isNotNullOrBlank(templateFormular)) {
            StringTokenizer st = new StringTokenizer(templateFormular, "+-*/()", true);
            boolean isFirst = true;
            while (st.hasMoreElements()) {
                element = st.nextElement().toString();
                isFirst = true;
                if (element.contains("{brand}")) {
                    formular.append("(");
                    for (String brand : brands) {
                        if (!isFirst) {
                            formular.append("+");
                        } else {
                            isFirst = false;
                        }

                        formular.append(element.replace("{brand}", brand));
                    }
                    formular.append(")");
                } else {
                    formular.append(element);
                }
            }

            newReportConfig.setFormularExpression(formular.toString());
        }

        return newReportConfig;
    }

    public static List<ReportConfig> getReportConifTreeByBuildPurchase(Map info) {
        String reportName = "库存预测_采购预测";
        String endString = "_采购预测";
        String selType = info.get("selType").toString();
        int z = 1;
        List<Lsh车型Model> list = lsh车型Repository.findBy品牌And级别And车型(info.get("selBrand").toString(), info.get("selClass").toString(), selType);
        //获取报表指标树　：Y轴维度
        List<ReportConfig> configs = new ArrayList<>();
        List<ReportConfig> reChildConfigs = Lists.newArrayList();
        ReportConfig reConfig = new ReportConfig();
        reConfig.setReportCode(reportName);
        reConfig.setAinCode(selType);
        reConfig.setParentCode("0");
        reConfig.setMatchItem(0);
        reConfig.setCategory("oneIndex");
        reConfig.setText(info.get("selClass").toString());
        for (Lsh车型Model model : list) {
            if (Strings.isNullOrEmpty(model.get车型详细())) {
                continue;
            }
            ReportConfig config = new ReportConfig();
            config.setReportCode(reportName);
            config.setAinCode(model.get车型详细() + endString);
            config.setParentCode(selType);
            config.setCategory("twoIndex");
            config.setMatchItem(1);
            config.setMatchKey("车款");
            config.setText(model.get车型详细());
            String appearance = model.getAppearance();
            config.setParentConfig(reConfig);
            if (!Strings.isNullOrEmpty(appearance)) {
                String[] array = appearance.split(";");
                List<ReportConfig> temp = new ArrayList<>();
                for (String code : array) {
                    ReportConfig childConfig = new ReportConfig();
                    childConfig.setReportCode(reportName);
                    childConfig.setAinCode(code + model.get车型详细() + endString);
                    childConfig.setMatchKey("新增库存");
                    childConfig.setParentCode(model.get车型详细() + endString);
                    childConfig.setCategory("threeIndex");
                    childConfig.setRemark(array.length + "");
                    childConfig.setMatchItem(0);
                    childConfig.setText(code);
                    childConfig.setProjectNameOrder(z + "");
                    childConfig.setParentConfig(config);
                    temp.add(childConfig);
                    z++;
                }
                config.setChildConfigs(temp);
                reChildConfigs.add(config);
            }
        }
        reConfig.setChildConfigs(reChildConfigs);
        configs.add(reConfig);
        return configs;
    }

    public static List<ReportConfig> getReportConifTreeByPermit(Map info) {
        String reportName = "库存预测_采购预测_报表导出";
        String endString = "_采购预测";
        int z = 1;
        List<Lsh车型Model> list = lsh车型Repository.getCarTreeByPermit(info.get("permit").toString());
        //获取报表指标树　：Y轴维度
        List<ReportConfig> configs = new ArrayList<>();
        List<String> brands = list.stream()
                .map(Lsh车型Model::get品牌)
                .distinct()
                .collect(Collectors.toList());
        for (String brand : brands) {  // 品牌
            List<ReportConfig> classConfigs = new ArrayList<>();
            ReportConfig reConfig = new ReportConfig();
            reConfig.setReportCode(reportName);
            reConfig.setAinCode(brand);
            reConfig.setParentCode("0");
            reConfig.setMatchItem(0);
            reConfig.setCategory("oneIndex");
            reConfig.setText(brand);
            List<String> carClasss = list.stream()
                    .filter(e -> e.get品牌().equals(brand) && !Strings.isNullOrEmpty(e.get级别()))
                    .map(Lsh车型Model::get级别)
                    .distinct()
                    .collect(Collectors.toList());
            for (String carClass : carClasss) {  // 级别
                List<ReportConfig> typeConfigs = new ArrayList<>();
                ReportConfig configClass = new ReportConfig();
                configClass.setReportCode(reportName);
                configClass.setAinCode(carClass + endString);
                configClass.setParentCode(brand);
                configClass.setCategory("twoIndex");
                configClass.setMatchItem(0);
                configClass.setMatchKey("级别");
                configClass.setText(carClass);
                configClass.setParentConfig(reConfig);
                List<String> carTypes = list.stream()
                        .filter(e -> e.get级别().equals(carClass) && !Strings.isNullOrEmpty(e.get车型()))
                        .map(Lsh车型Model::get车型)
                        .distinct()
                        .collect(Collectors.toList());
                for (String carType : carTypes) {  // 车型
                    List<ReportConfig> detailConfigs = new ArrayList<>();
                    ReportConfig configType = new ReportConfig();
                    configType.setReportCode(reportName);
                    configType.setAinCode(carType + endString);
                    configType.setParentCode(carClass + endString);
                    configType.setCategory("threeIndex");
                    configType.setMatchItem(0);
                    configType.setMatchKey("车型");
                    configType.setText(carType);
                    configType.setParentConfig(configClass);
                    List<Lsh车型Model> carDetails = list.stream()
                            .filter(e -> e.get车型().equals(carType) && !Strings.isNullOrEmpty(e.get车型详细()))
                            .collect(Collectors.toList());
                    for (Lsh车型Model model : carDetails) {  // 车型详细
                        ReportConfig config = new ReportConfig();
                        config.setReportCode(reportName);
                        config.setAinCode(model.get车型详细() + endString);
                        config.setParentCode(carType + endString);
                        config.setCategory("fourIndex");
                        config.setMatchItem(1);
                        config.setMatchKey("车款");
                        config.setText(model.get车型详细());
                        String appearance = model.getAppearance();
                        config.setParentConfig(configType);
                        if (!Strings.isNullOrEmpty(appearance)) {
                            String[] array = appearance.split(";");
                            List<ReportConfig> temp = new ArrayList<>();
                            for (String code : array) {  // 颜色
                                ReportConfig childConfig = new ReportConfig();
                                childConfig.setReportCode(reportName);
                                childConfig.setAinCode(code + model.get车型详细() + endString);
                                childConfig.setMatchKey("新增库存");
                                childConfig.setParentCode(model.get车型详细() + endString);
                                childConfig.setCategory("fiveIndex");
                                childConfig.setRemark(array.length + "");
                                childConfig.setMatchItem(0);
                                childConfig.setText(code);
                                childConfig.setProjectNameOrder(z + "");
                                childConfig.setParentConfig(config);
                                temp.add(childConfig);
                                z++;
                            }
                            config.setChildConfigs(temp);
                            detailConfigs.add(config);
                        }
                    }
                    configType.setChildConfigs(detailConfigs);
                    typeConfigs.add(configType);
                }
                configClass.setChildConfigs(typeConfigs);
                classConfigs.add(configClass);
            }
            reConfig.setChildConfigs(classConfigs);
            configs.add(reConfig);
        }
        return configs;
    }

    @Autowired
    public void setLsh经销商表Repository(Lsh经销商表Repository lsh经销商表Repository) {
        LineContextUtil.lsh经销商表Repository = lsh经销商表Repository;
    }

    @Resource(name = "TimelineConvertor")
    public void setTimelineConvertor(IReportDataConvertor timelineConvertor) {
        LineContextUtil.timelineConvertor = timelineConvertor;
    }

    @Resource(name = "OrglineConvertor")
    public void setOrglineConvertor(IReportDataConvertor orglineConvertor) {
        LineContextUtil.orglineConvertor = orglineConvertor;
    }

    @Resource(name = "BaselineConvertor")
    public void setBaselineConvertor(IReportDataConvertor baselineConvertor) {
        LineContextUtil.baselineConvertor = baselineConvertor;
    }

    @Resource(name = "OtherBaselineConvertor")
    public void setBaseOtherlineConvertor(IReportDataConvertor baseOtherlineConvertor) {
        LineContextUtil.baseOtherlineConvertor = baseOtherlineConvertor;
    }

    @Resource(name = "CarModellineConvertor")
    public void setCarModellineConvertor(IReportDataConvertor carModellineConvertor) {
        LineContextUtil.carModellineConvertor = carModellineConvertor;
    }

    @Autowired
    public void setUserRepository(用户Repository userRepository) {
        LineContextUtil.userRepository = userRepository;
    }

    @Autowired
    public void setReportConfigRepository(ReportConfigRepository reportConfigRepository) {
        LineContextUtil.reportConfigRepository = reportConfigRepository;
    }

    @Autowired
    public void setLsh车型Repository(Lsh车型Repository lsh车型Repository) {
        LineContextUtil.lsh车型Repository = lsh车型Repository;
    }

    @Resource
    public void setLsh金融机构设置Repository(Lsh金融机构设置Repository lsh金融机构设置Repository) {
        LineContextUtil.lsh金融机构设置Repository = lsh金融机构设置Repository;
    }

    @Autowired
    public void setCarRepository(CarRepository carRepository) {
        LineContextUtil.carRepository = carRepository;
    }

    @Autowired
    public void setBrandService(BrandService brandService) {
        LineContextUtil.brandService = brandService;
    }

    @Autowired
    public void setItask基础设置Repository(Itask基础设置Repository itask基础设置Repository) {
        LineContextUtil.itask基础设置Repository = itask基础设置Repository;
    }

}
